package dev.ece.suit.loader.models.obj;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.tools.NormalUtils;

public class ObjFace extends dev.ece.suit.loader.Face {

	private int[] textureCoordIndice;
	
	private int[] normlIndice;
	
	private boolean hasNormal;
	
	public ObjFace(int[] indice, int[] textureCoordIndice) {
		this(indice, textureCoordIndice, null);
	}
	
	public ObjFace(int[] indice, int[] textureCoordIndice, int[] normlIndice) {
		super(indice);
		this.textureCoordIndice = textureCoordIndice;
		this.normlIndice = normlIndice;
		this.hasNormal = normlIndice != null;
	}
	
	public void fillData(ObjMesh mesh, List<Vector3f> vertice, List<Vector2f> textureCoords, List<Vector3f> normals) {
		Vector3f[] v = new Vector3f[3];
		Vector2f[] u = new Vector2f[3];
		Vector3f[] n = new Vector3f[3];
		boolean hasNormal = this.isHasNormal() && !normals.isEmpty();
		for(int i=0; i<3; i++) {
			v[i] = vertice.get(this.getIndice()[i]);
			u[i] = textureCoords.get(this.getTextureCoordIndice()[i]);
			if(hasNormal) {
				n[i] = normals.get(this.getNormlIndice()[i]);
			} else {
				n[i] = new Vector3f();
			}
		}
		//没有法线
		if(!hasNormal) {
			//计算法线
			NormalUtils.buildNormal(v[2], v[0], v[1], n[0]);
			NormalUtils.buildNormal(v[0], v[1], v[2], n[1]);
			NormalUtils.buildNormal(v[1], v[2], v[0], n[2]);
		}
		for(int i=0; i<3; i++) {
			mesh.getVertice().add(v[i]);
			mesh.getTextureCoords().add(u[i]);
			mesh.getNormals().add(n[i]);
		}
	}
	
	public static ObjFace createFace(String[] data) {
		int[] indice = new int[3];
		int[] textureCoordIndice = new int[3];
		int[] normlIndice = new int[3];
		String[] col = null; 
		boolean hasNormal = false;
		for(int i=0; i<3; i++) {
			col = StringUtils.split(data[i + 1], "/");
			hasNormal = col.length > 2;
			indice[i] = NumberUtils.toInt(col[0]) - 1;
			textureCoordIndice[i] = NumberUtils.toInt(col[1]) - 1;
			if(hasNormal) {
				normlIndice[i] = NumberUtils.toInt(col[2]) - 1;
			}
		}
		return hasNormal ? new ObjFace(indice, textureCoordIndice, normlIndice) : new ObjFace(indice, textureCoordIndice);
	}
	
	public int[] getTextureCoordIndice() {
		return textureCoordIndice;
	}

	public int[] getNormlIndice() {
		return normlIndice;
	}

	public boolean isHasNormal() {
		return hasNormal;
	}

}
